#include <myheader_c_plus.h>
#include <functional>
using std::endl;
using std::cout;
using std::bind;
using std::function;
class Figure
{
public:
    using displayFunctype = function<void()>;
    using areaFunctype = function<double()>;

    //绑定回调函数
    void setDisplayfunc(displayFunctype && dis)
    {
        disfunc = std::move(dis);
    }
    void setAreafunc(areaFunctype && getArea)
    {
        areafunc = std::move(getArea);
    }


    //执行回调函数
    void display()
    {
        disfunc();
    }

    double getArea()
    {
        return areafunc();
    }

    displayFunctype disfunc;
    areaFunctype areafunc;

};
class Circle
{
public:
    Circle(int r)
        :_r(r)
    {

    }

    void display()
    {
        cout << "Circle" << endl; 
    }

    double getArea()
    {
        return 3.14 * _r;
    }


private:
    int _r;
};
class Traingle
{
public:
    Traingle(int a, int b, int c)
        :_a(a)
         ,_b(b)
         ,_c(c)
    {

    }

    void display()
    {
        cout << "Tranigle" << endl; 
    }

    double getArea()
    {
        // 计算半周长
        double s = (_a + _b + _c) / 2;

        // 使用海伦公式计算面积
        return std::sqrt(s * (s - _a) * (s - _b) * (s - _c));
    }


private:
    int _a;
    int _b;
    int _c;
};

int main(int argc, char *argv[])
{
    Traingle traingle(3,4,5);
    Circle circle(2);

    Figure fi;
    fi.setDisplayfunc(bind(&Traingle::display, &traingle));
    fi.setAreafunc(bind(&Traingle::getArea, &traingle));
    fi.display();
    cout << "traingle area = " << fi.getArea() << endl;

    fi.setDisplayfunc(bind(&Circle::display, &circle));
    fi.setAreafunc(bind(&Circle::getArea, &circle));
    fi.display();
    cout << "circle area = " << fi.getArea() << endl;


    
    

    return 0;
}

